// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RGBDCameraModel.cs" company="Microsoft Corporation">
// The MIT License (MIT)
// 
// Copyright (c) 2014, Microsoft Corporation
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.Robotics.Vision.Visualization
{
    using System;
    using System.Windows;

    using Microsoft.Robotics.Numerics;
    using Microsoft.Robotics.Visualization;
    
    /// <summary>
    /// Sample model that demonstrates how to visualize a video stream
    /// </summary>
    public sealed class RGBDCameraModel : Model
    {
        /// <summary>
        /// The mouse position
        /// </summary>
        private Vector2 mousePosition;

        /// <summary>
        /// A flag indicating if the mouse is down
        /// </summary>
        private bool mouseDown;

        /// <summary>
        /// The wheel delta;
        /// </summary>
        private int wheelDelta;

        /// <summary>
        /// Gets or sets the mouse start position
        /// </summary>
        public Vector2 MouseStart
        {
            get
            {
                return this.mousePosition;
            }

            set
            {
                this.mousePosition = value;
                this.mouseDown = true;
            }
        }

        /// <summary>
        /// Gets or sets the mouse move
        /// </summary>
        public Vector2 MouseMove
        {
            get
            {
                return this.mousePosition;
            }

            set
            {
                if (this.mouseDown)
                {
                    ////if ((new Vector2(0.5, 0.5) - value).L2Norm() > 0.3)
                    ////{
                    ////    Vector3 mousePoint = new Vector3(value.X, value.Y, 0);
                    ////    Vector3 prevPoint = new Vector3(this.mousePosition.X, this.mousePosition.Y, 0);
                    ////    Vector3 center = new Vector3(0.5, 0.5, 0);

                    ////    Vector3 cross = Vector3.Cross(mousePoint - center, prevPoint - center);
                    ////    if (cross.Z > 0)
                    ////    {
                    ////        this.Roll = -0.1f;
                    ////    }
                    ////    else if (cross.Z < 0)
                    ////    {
                    ////        this.Roll = 0.1f;
                    ////    }
                    ////}
                    ////else
                    ////{
                        if (value.Y < this.mousePosition.Y)
                        {
                            this.Pitch = -0.1f;
                        }
                        else if (value.Y > this.mousePosition.Y)
                        {
                            this.Pitch = 0.1f;
                        }

                        if (value.X < this.mousePosition.X)
                        {
                            this.Yaw = 0.1f;
                        }
                        else if (value.X > this.mousePosition.X)
                        {
                            this.Yaw = -0.1f;
                        }
                    ////}

                    this.mousePosition = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the mouse up
        /// </summary>
        public Vector2 MouseUp
        {
            get
            {
                return this.mousePosition;
            }

            set
            {
                this.Yaw = 0;
                this.Pitch = 0;
                this.Roll = 0;
                this.mouseDown = false;
            }
        }

        /// <summary>
        /// Gets or sets the wheel delta
        /// </summary>
        public int Delta
        {
            get
            {
                return this.wheelDelta;
            }

            set
            {
                this.wheelDelta = value;
            }
        }

        /// <summary>
        /// Gets or sets the depth image.
        /// </summary>
        public VideoFrame VideoFrame { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether the view orientation is depth or color
        /// </summary>
        public bool DisplayColor { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether the view orientation is depth or color
        /// </summary>
        public bool DisplayDepth { get; set; }

        /// <summary>
        /// Gets or sets the blend from color to depth
        /// </summary>
        public float Blend { get; set; }

        /// <summary>
        /// Gets or sets the max distance to render
        /// </summary>
        public float MaxValue { get; set; }

        /// <summary>
        /// Gets or sets the minimum distance to render
        /// </summary>
        public float MinValue { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether to cut off the color past a range
        /// </summary>
        public bool LimitColor { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether or not to render the point cloud
        /// </summary>
        public bool PointCloud { get; set; }

        /// <summary>
        /// Gets or sets the yaw
        /// </summary>
        public float Yaw { get; set; }

        /// <summary>
        /// Gets or sets the pitch
        /// </summary>
        public float Pitch { get; set; }

        /// <summary>
        /// Gets or sets the roll
        /// </summary>
        public float Roll { get; set; }
    }
}
